package
{
	import com.Dispatcher;
	import com.ModuleCommand;
	import com.map.GridVO;
	import com.map.LoadMapCase;
	import com.map.MapDatas;
	import com.map.MapImgVO;
	import com.map.astar.AStar;
	import com.unit.SceneUnit;
	import com.util.Point3D;
	import com.util.iso.IsoUtil;
	
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	public class MyGame extends Sprite
	{
		private var loadMap:LoadMapCase;
		private var mapDataManager:MapDatas;
		private var role:SceneUnit;
		private var curP:Point3D;	
		private var mapLayer:Sprite;
		private var sceneLayer:Sprite;
		private var gridLayer:Sprite;
		
		private var _astar:AStar;
		
		public function MyGame()
		{
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			
			mapLayer = new Sprite;
			addChild(mapLayer);
			sceneLayer = new Sprite;
			addChild(sceneLayer);
			gridLayer = new Sprite;
			addChild(gridLayer);
			
			curP = new Point3D(2500, 0, 2500);
			tarP = curP.clone();
			role = new SceneUnit;
			stage.addChild(role);
			stage.setChildIndex(role, stage.numChildren - 1);
			initModules();	
			initListeners();
				
			run();
		}
		
		private function showInfo():void {
			
		}
		
		private function initModules():void {
			loadMap = LoadMapCase.getInstance();
			mapDataManager = MapDatas.getInstance();
			mapDataManager.mainSprite = this;
			_astar = new AStar(mapDataManager.mapGrid);
		}
		
		private function get MIN_DIST():Number {
			return role.speed * 1.5;
		}
		
		private function initListeners():void {
			Dispatcher.register(ModuleCommand.STAGE_RESIZE, displayMap);
			this.addEventListener(MouseEvent.CLICK, move);
			this.addEventListener(Event.ENTER_FRAME, updateMap);
		}
		
		private var hasInited:Boolean = false;
		private var isMoving:Boolean = true;
		private function updateMap(e:Event = null):void {
			if(hasInited) {
				var dist:Number = tarP.distance(curP);
//				var sinAng:Number = (tarP.y - curP.y) / dist;
//				var cosAng:Number = (tarP.x - curP.x) / dist;
				
				if(isMoving || !e) {
					if(e) {	
//						curP.x += int(role.speed * cosAng);	//用Math.ceil(xx)的竟然会算出NaN
//						curP.y += int(role.speed * sinAng);
						var testP:Point3D = curP.clone();
						testP.step(tarP, role.speed);
						if(!mapDataManager.isPointInMap(testP))
							return;
						else
							curP.step(tarP, role.speed);
						testP = null;
					}
//					mapDataManager.putPointIntoMap(curP);
					var offsetP:Point = mapDataManager.getOffset(curP);
					var flatCur:Point = IsoUtil.isoToFlat(curP);
					var mapCurX:Number = flatCur.x - mapDataManager.mapGrid.oriX;
					var mapCurY:Number = flatCur.y - mapDataManager.mapGrid.oriY;
//					role.x = curP.x - offsetP.x;
//					role.y = curP.y - offsetP.y;
					role.x = mapCurX - offsetP.x;
					role.y = mapCurY - offsetP.y;
					//todo 必须要把场景元素抽离出去，role应该属于这个舞台，而非某一层
					trace("role.x:", role.x, "role.y:", role.y);
//					gridLayer.x = mapDataManager.mapGrid.oriX - offsetP.x;
//					gridLayer.y = mapDataManager.mapGrid.oriY  - offsetP.y;
					var viewShowIndexRec:Rectangle = mapDataManager.getViewIndexRec(curP);
					var mapInfos:Array = mapDataManager.mapImgArr;				
					for(var i:int = viewShowIndexRec.x; i <= viewShowIndexRec.x + viewShowIndexRec.width; i++) {
						for(var j:int = viewShowIndexRec.y; j <= viewShowIndexRec.y + viewShowIndexRec.height; j++) {
							var imgInfo:MapImgVO = (mapInfos[j * MapDatas.COL_NUM + i]) as MapImgVO;
							if(!imgInfo) {
								loadMap.startLoad(j, i, offsetP.x, offsetP.y, mapLayer);
							}
						}
					}
					//可能有问题
//					mapLayer.x = -offsetP.x;
//					mapLayer.y = -offsetP.y;
					this.x = -offsetP.x - mapDataManager.mapGrid.oriX;
					this.y = -offsetP.y - mapDataManager.mapGrid.oriY;
					
					if(dist < role.speed) {		//到达目标点
						if(curPath && pathIndex < curPath.length) {
							var grid:GridVO = curPath[pathIndex++];
							var p3d:Point3D = new Point3D(MapDatas.ISO_GRID_SIZE * grid.xIndex, 0,
								MapDatas.ISO_GRID_SIZE * grid.zIndex);
							tarP = p3d;
//							tarP.x = p3d.x + 50;
//							tarP.z = p3d.z + 50;
//							tarP = IsoUtil.isoToFlat(p3d);
//							tarP.x += mapDataManager.map_width >> 1;
//							tarP.y += 50/* - (mapDataManager.map_width >> 2)*/;
						} else {
							isMoving = false;
						}
					}
				} else {
					
				}
			}
		}
		
		private var tarP:Point3D;	//对应真实地图的点
		private var pathIndex:int;
		private var curPath:Array;
		private function move(e:MouseEvent):void {
			var offsetP:Point = mapDataManager.getOffset(curP);	//当前地图点对应总地图的偏移点
			var mapTarP:Point = new Point;
			mapTarP.x = e.stageX + offsetP.x;						
			mapTarP.y = e.stageY + offsetP.y;		//目标点在总地图的真实位置
			tarP = IsoUtil.flatToIso(new Point(mapDataManager.mapGrid.oriX + mapTarP.x,
				mapDataManager.mapGrid.oriY + mapTarP.y));	//目标点在等角坐标系中的真实点
//			tarP.x = e.stageX + offsetP.x;						
//			tarP.y = e.stageY + offsetP.y;		//目标点在总地图的真实位置
//			var x:Number = tarP.x - (mapDataManager.map_width >> 1);	//被>>运算符坑的好惨，如果不加括号的话
//			var y:Number = tarP.y + (mapDataManager.map_width >> 2);
//			var p3d:Point3D = IsoUtil.flatToIso(new Point(x, y));
//			trace("xIndex:", int(p3d.x / MapDatas.ISO_GRID_SIZE), "zIndex:", int(p3d.z / MapDatas.ISO_GRID_SIZE));
//			trace("tarPx:", tarP.x, "tarPy", tarP.y);
//			var curOffX:Number = curP.x - (mapDataManager.map_width >> 1);
//			var curOffY:Number = curP.y + (mapDataManager.map_width >> 2);
//			var curP3d:Point3D = IsoUtil.flatToIso(new Point(curP.x, curP.y));
			/*var curPzIndex:int = int(curP.z / MapDatas.ISO_GRID_SIZE);
			var curPxIndex:int = int(curP.x / MapDatas.ISO_GRID_SIZE);
			var stNode:GridVO = mapDataManager.getGridVOByXz(curPxIndex, curPzIndex);*/
			
//			var tarOffX:Number = tarP.x - (mapDataManager.map_width >> 1);
//			var tarOffY:Number = tarP.y + (mapDataManager.map_width >> 2);
//			var tarP3d:Point3D = IsoUtil.flatToIso(new Point(tarOffX, tarOffY));
			/*var tarPzIndex:int = int(tarP.z / MapDatas.ISO_GRID_SIZE);
			var tarPxIndex:int = int(tarP.x / MapDatas.ISO_GRID_SIZE);
			var endNode:GridVO = mapDataManager.getGridVOByXz(tarPxIndex, tarPzIndex);
			
			curPath = _astar.findPath(stNode, endNode);
			if(curPath && curPath.length > 0) {
				pathIndex = 1;
				drawPath(curPath);
				var grid:GridVO = curPath[pathIndex++];
				var p3d:Point3D = new Point3D(MapDatas.ISO_GRID_SIZE * grid.xIndex, 0,
					MapDatas.ISO_GRID_SIZE * grid.zIndex);
				tarP.x = p3d.x + 50;
				tarP.z = p3d.y + 50;*/
//				tarP = IsoUtil.isoToFlat(p3d);
//				tarP.x += mapDataManager.map_width >> 1;
//				tarP.y += 50 - (mapDataManager.map_width >> 2);
				isMoving = true;
			/*} else {
				isMoving = false;
			}*/
			trace("moving");
				
		}
		
		private function displayMap():void {
			if(!hasInited) {
				hasInited = true;
				mapLayer.x = -mapDataManager.map_width >> 1;
				mapLayer.y = mapDataManager.map_width >> 2;
				sceneLayer.x = mapLayer.x;
				sceneLayer.y = mapLayer.y;
//				gridLayer.x = mapLayer.x;
//				gridLayer.y = mapLayer.y;
				drawBarrier();
			}
			updateMap();
		}
		
		private function run():void {
			displayMap();
		}
		
		private function drawBarrier():void {
			mapDataManager.mapGrid.genBarrier();
			var isoTiles:Array = mapDataManager.mapGrid.isoTiles;
			for each(var gridArr:Array in isoTiles) { 
				for each(var grid:GridVO in gridArr) {
					if(!grid.isValid) {
						var p3d1:Point3D = new Point3D(MapDatas.ISO_GRID_SIZE * grid.xIndex, 0, MapDatas.ISO_GRID_SIZE * grid.zIndex);
						var p3d2:Point3D = new Point3D(MapDatas.ISO_GRID_SIZE * (grid.xIndex+1), 0, MapDatas.ISO_GRID_SIZE * grid.zIndex);
						var p3d3:Point3D = new Point3D(MapDatas.ISO_GRID_SIZE * (grid.xIndex+1), 0, MapDatas.ISO_GRID_SIZE * (grid.zIndex+1));
						var p3d4:Point3D = new Point3D(MapDatas.ISO_GRID_SIZE * grid.xIndex, 0, MapDatas.ISO_GRID_SIZE * (grid.zIndex+1));
						var p1:Point = IsoUtil.isoToFlat(p3d1);
						var p2:Point = IsoUtil.isoToFlat(p3d2);
						var p3:Point = IsoUtil.isoToFlat(p3d3);
						var p4:Point = IsoUtil.isoToFlat(p3d4);
						
						var g:Graphics = gridLayer.graphics; 
						g.lineStyle(0);
						g.beginFill(0x0078cd, 0.4);
						g.moveTo(p1.x, p1.y);
						g.lineTo(p2.x, p2.y);
						g.lineTo(p3.x, p3.y);
						g.lineTo(p4.x, p4.y);
						g.lineTo(p1.x, p1.y);
					}
				}
			}
		}
		
		private var pathSp:Sprite;
		private function drawPath(path:Array):void {
			if(!pathSp) {
				pathSp = new Sprite;
				gridLayer.addChild(pathSp);
			}
			var g:Graphics = pathSp.graphics;
			g.clear();
			g.lineStyle(5, 0xff1234);
			var curOffX:Number = curP.x - (mapDataManager.map_width >> 1);
			var curOffY:Number = curP.y + (mapDataManager.map_width >> 2);
			//curX, curY在等角layer的偏移
			g.moveTo(curOffX, curOffY);
			if(path) {
				for(var i:int = 1; i < path.length; i++) {
					var grid:GridVO = path[i] as GridVO;
					var p3d:Point3D = new Point3D(MapDatas.ISO_GRID_SIZE * grid.xIndex, 0, MapDatas.ISO_GRID_SIZE * grid.zIndex);
					var p:Point = IsoUtil.isoToFlat(p3d);
					g.lineTo(p.x, p.y + 50);
				}
			} else {
				trace("Can't walk!");
			}
		}
	}
}